package com.xyh.transaction.service.imp;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.meilisearch.sdk.exceptions.MeilisearchException;
import com.meilisearch.sdk.model.Searchable;
import com.xyh.transaction.common.*;
import com.xyh.transaction.entity.*;
import com.xyh.transaction.entity.dto.goods.EditOrAddGoodsDto;
import com.xyh.transaction.entity.dto.goods.GoodsDto;
import com.xyh.transaction.entity.dto.user.ArrDto;
import com.xyh.transaction.entity.vo.*;
import com.xyh.transaction.excel.ExcelGoodsVo;
import com.xyh.transaction.excel.ImportGoodsVoListener;
import com.xyh.transaction.exception.BusinessException;
import com.xyh.transaction.listener.MapGoodsImageEvent;
import com.xyh.transaction.mapper.*;
import com.xyh.transaction.service.GoodsService;
import com.xyh.transaction.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private ImageMapper imageMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private GoodsStatisticMapper goodsStatisticMapper;

    @Autowired
    private GoodsEvaluationMapper goodsEvaluationMapper;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private MeiliSearchUtil meiliSearchUtil;

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @org.springframework.beans.factory.annotation.Value("${image.cosBucketName}")
    private String bucketName;

    @org.springframework.beans.factory.annotation.Value("${meilisearch.enabled}")
    private Boolean meiliSearchEnabled;

    @Autowired
    private ImageUtils imageUtils;

    @Override
    public List<GoodsVo> getUrgentGoodsList() {
        return goodsMapper.findAll(new Goods()).stream()
                // 按商品创建时间，展示最新创建（发布）的商品
                .sorted(Comparator.comparing(BaseEntity::getCreateTime, Comparator.reverseOrder()))
                .limit(4)
                .map(goods -> {
                    GoodsVo goodsVo = MappingUtil.mapObject(goods, GoodsVo.class);
                    eventPublisher.publishEvent(new MapGoodsImageEvent(goods, goodsVo));
                    return goodsVo;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<GoodsVo> getHomeGoodsList() {
        // 先写死数据测试
        ArrayList<GoodsVo> goodsVos = new ArrayList<>();
        goodsVos.add(new GoodsVo(1, "首页商品展示测试商品1", "首页商品展示测试商品1描述", new BigDecimal("1200"), Constant.DEFAULT_GOODS));
        goodsVos.add(new GoodsVo(2, "首页商品展示测试商品2", "首页商品展示测试商品2描述", new BigDecimal("1300"), Constant.DEFAULT_GOODS));
        goodsVos.add(new GoodsVo(3, "首页商品展示测试商品3", "首页商品展示测试商品3描述", new BigDecimal("1400"), Constant.DEFAULT_GOODS));
        goodsVos.add(new GoodsVo(4, "首页商品展示测试商品4", "首页商品展示测试商品4描述", new BigDecimal("1500"), Constant.DEFAULT_GOODS));

        return goodsVos;
    }

    // TODO 因为要统计用户访问商品详情，这个方法只给用户访问，后期有其他需要访问另写方法
    @Override
    public GoodsDetailVo getGoodsDetail(Integer id) {
        Goods goods = goodsMapper.findById(id);
        if (goods == null) {
            throw new IllegalArgumentException("商品不存在");
        }

        // 组装基础信息
        String sellerName = userMapper.findById(goods.getCreateBy()).getUsername();
        GoodsVo goodsVo = new GoodsVo();
        eventPublisher.publishEvent(new MapGoodsImageEvent(goods, goodsVo));
        List<String> images = goodsVo.getPictures().stream().map(ImageVo::getUrl).collect(Collectors.toList());
        Category category = categoryMapper.findById(goods.getCategoryId());
        Category parentCategory = category != null ? categoryMapper.findById(category.getParentId()) : null;

        // 构建GoodsDetailVo
        GoodsDetailVo goodsDetailVo = new GoodsDetailVo();
        goodsDetailVo.setId(String.valueOf(goods.getId()));
        goodsDetailVo.setName(goods.getName());
        goodsDetailVo.setPrice(String.valueOf(goods.getPrice()));
        goodsDetailVo.setStock(goods.getStock());
        goodsDetailVo.setSellerName(sellerName);
        goodsDetailVo.setDetails(buildDetails(images, category, sellerName));
        goodsDetailVo.setBrand(buildBrand());
        goodsDetailVo.setEvaluationInfo(buildEvaluationInfo());
        goodsDetailVo.setHotByDay(buildHotByDayList());
        goodsDetailVo.setSimilarProducts(buildSimilarProducts());
        goodsDetailVo.setSkus(buildSkus(goods, images));
        goodsDetailVo.setMainPictures(images.isEmpty() ?
                Constant.DEFAULT_GOODS_LIST.stream()
                        .map(s -> imageUtils.buildImageUrl(s))
                        .collect(Collectors.toList())
                : images);
        goodsDetailVo.setSpecs(buildSpecs(goods));

        // 设置分类信息
        List<Category> categories = new ArrayList<>();
        if (category != null) {
            categories.add(category);
        }
        if (parentCategory != null) {
            categories.add(parentCategory);
        }
        goodsDetailVo.setCategories(categories);

        return goodsDetailVo;
    }

    private Brand buildBrand() {
        // 组装Brand
        Brand brand = new Brand();
        brand.setId("1");
        brand.setName("Nike");
        brand.setNameEn("Nike");
        brand.setLogo("logo_url");
        brand.setPicture("picture_url");
        return brand;
    }

    private EvaluationInfo buildEvaluationInfo() {
        EvaluationInfo evaluationInfo = new EvaluationInfo();
        evaluationInfo.setId("1");
        evaluationInfo.setScore(4.5);
        evaluationInfo.setContent("Good product!");
        evaluationInfo.setPraiseCount(10);
        evaluationInfo.setCreateTime("2024-02-29");
        evaluationInfo.setPraisePercent(90.0);
        return evaluationInfo;
    }

    private List<HotByDay> buildHotByDayList() {
        List<HotByDay> hotByDayList = new ArrayList<>();
        HotByDay hotByDay = new HotByDay();
        hotByDay.setId("1");
        hotByDay.setName("monkey A");
        hotByDay.setDesc("monkey A");
        hotByDay.setPrice("100.0");
        hotByDay.setPicture(Constant.DEFAULT_GOODS);
        hotByDay.setOrderNum(50);
        hotByDayList.add(hotByDay);
        return hotByDayList;
    }

    private List<SimilarProduct> buildSimilarProducts() {
        List<SimilarProduct> similarProducts = new ArrayList<>();
        SimilarProduct similarProduct = new SimilarProduct();
        similarProduct.setId("2");
        similarProduct.setName("monkey B");
        similarProduct.setDesc("monkey B");
        similarProduct.setPrice("120.0");
        similarProduct.setPicture(Constant.DEFAULT_GOODS);
        similarProduct.setOrderNum(40);
        similarProducts.add(similarProduct);
        return similarProducts;
    }

    private List<Sku> buildSkus(Goods goods, List<String> images) {
        List<Sku> skus = new ArrayList<>();
        Sku sku = new Sku();
        sku.setId("1");
        sku.setSkuCode("1");
        sku.setPrice(String.valueOf(goods.getPrice()));
        sku.setOldPrice("90.0");
        sku.setInventory(10);
        sku.setPicture(images.isEmpty() ? Constant.DEFAULT_GOODS : images.get(0));
        sku.setSpecs(buildSkuSpecs(goods));

        Spec spec = buildSpecs(goods).get(0);
        SkuSpec skuSpec = new SkuSpec();
        skuSpec.setName(spec.getName());
        skuSpec.setValueName(spec.getValueName());
        // 设置Sku的Specs
        sku.getSpecs().add(skuSpec);
        skus.add(sku);
        return skus;
    }

    private List<SkuSpec> buildSkuSpecs(Goods goods) {
        List<SkuSpec> skuSpecs = new ArrayList<>();
        SkuSpec skuSpec = new SkuSpec();
        skuSpec.setName("成色");
        skuSpec.setValueName(goods.getCondition().getDetail());
        skuSpecs.add(skuSpec);
        return skuSpecs;
    }

    private List<Spec> buildSpecs(Goods goods) {
        // 创建Spec对象
        Spec spec = new Spec();
        spec.setName("成色");
        spec.setId("1");
        spec.setValues(new ArrayList<>());
        String detail = goods.getCondition().getDetail();
        Value value = new Value();
        value.setName(detail);
//        value.setPicture(images.get(0));
        value.setDesc(detail);
        spec.getValues().add(value);
        return Collections.singletonList(spec);
    }


    private Details buildDetails(List<String> images, Category category, String sellerName) {
        Details details = new Details();
        details.setPictures(images);

        List<Property> properties = new ArrayList<>();
        properties.add(new Property("卖家", sellerName));
        if (category != null) {
            properties.add(new Property("类别", category.getName()));
        }
        details.setProperties(properties);

        return details;
    }


    @Override
    public List<GoodsVo> getHotList() {
        ArrayList<GoodsVo> hotList = new ArrayList<>();

        GoodsVo goodsVo = new GoodsVo();
        goodsVo.setId(1);
        goodsVo.setPrice(new BigDecimal("123"));
        goodsVo.setPicture(Constant.DEFAULT_GOODS);
        goodsVo.setName("test111");
        goodsVo.setOrderNum(1111);
        goodsVo.setDesc("test111 desc");

        GoodsVo goodsVo1 = new GoodsVo();
        goodsVo1.setId(1);
        goodsVo1.setPrice(new BigDecimal("12113"));
        goodsVo1.setPicture(Constant.DEFAULT_GOODS);
        goodsVo1.setName("test111");
        goodsVo1.setOrderNum(1111);
        goodsVo1.setDesc("test111 desc");

        GoodsVo goodsVo2 = new GoodsVo();
        goodsVo2.setId(1);
        goodsVo2.setPrice(new BigDecimal("444123"));
        goodsVo2.setPicture(Constant.DEFAULT_GOODS);
        goodsVo2.setName("test111");
        goodsVo2.setOrderNum(1111);
        goodsVo2.setDesc("test111 desc");

        hotList.add(goodsVo);
        hotList.add(goodsVo1);
        hotList.add(goodsVo2);
        return hotList;
    }

    @Override
    public PageInfo<GoodsVo> getGoodsList(GoodsDto goodsDto) {
        Integer pageSize = goodsDto.getPageSize();
        Integer pageNum = goodsDto.getPageNum();

        if (pageNum != null && pageSize != null) {
            pageNum = pageNum <= 0 ? 1 : pageNum;
            pageSize = pageSize <= 0 ? 10 : pageSize; // 默认显示10条
            PageHelper.startPage(pageNum, pageSize);
        }

        Goods goods = MappingUtil.mapObject(goodsDto, Goods.class);
        if (goodsDto.getCategoryName() != null) {
            goods.setCategoryId(categoryMapper.findByName(goodsDto.getCategoryName()).getId());
        }
        if (goodsDto.getConditionName() != null) {
            HashMap<String, GoodsCondition> conditionMap = new HashMap<>();
            for (GoodsCondition condition : GoodsCondition.values()) {
                conditionMap.put(condition.getDetail(), condition);
            }
            goods.setCondition(conditionMap.get(goodsDto.getConditionName()));
        }

        // 如果是非管理员角色，只显示当前账号创建的商品
        if (!Current.getCurrentUser().getRoles().stream()
                .map(Role::getId).collect(Collectors.toList())
                .contains(UserRole.Admin.getCode())) {
            goods.setCreateBy(Current.getCurrentUser().getUser().getId());
        }
        List<Goods> goodsList = goodsMapper.findAll(goods);
        List<GoodsVo> goodsVos = goodsList.stream().map(goods1 -> {
            GoodsVo goodsVo = MappingUtil.mapObject(goods1, GoodsVo.class);
            goodsVo.setCategoryName(categoryMapper.findById(goods1.getCategoryId()).getName());
            goodsVo.setConditionName(goods1.getCondition().getDetail());
            // 映射图片操作
            eventPublisher.publishEvent(new MapGoodsImageEvent(goods1, goodsVo));
            return goodsVo;
        }).collect(Collectors.toList());

        PageInfo pageInfo = new PageInfo<>(goodsList);
        pageInfo.setList(goodsVos);

        return pageInfo;
    }

    @Override
    public void deleteGoods(ArrDto arrDto) throws MeilisearchException {
        Integer[] ids = arrDto.getId();
        if (ids != null) {
            goodsMapper.delete(ids);
            // 增量更新meilisearch数据
            meiliSearchUtil.deleteDocument("goods", ids);
            // 删除cos中图片
            ArrayList<String> keys = new ArrayList<>();
            Arrays.stream(ids).map(id -> goodsMapper.findById(id)).forEach(goods -> {
                getGoodsImageUrl(goods, keys);
            });
            CosImageUtil.deleteBatchImage(bucketName, keys);
        }
    }

    private void getGoodsImageUrl(Goods goods, ArrayList<String> keys) {
        GoodsVo goodsVo = new GoodsVo();
        eventPublisher.publishEvent(new MapGoodsImageEvent(goods, goodsVo));
        List<String> imageUrlKeys = goodsVo.getPictures().stream()
                .filter(imageVo -> !Objects.equals(imageVo.getUrl(), Constant.DEFAULT_GOODS)) // 默认图片不用删除
                .map(imageVo -> {
                    URL url;
                    try {
                        url = new URL(imageVo.getUrl());
                    } catch (MalformedURLException e) {
                        log.error("商品: {}url错误，无法解析", goodsVo.getName(), e);
                        throw new BusinessException("图片url错误", e);
                    }
                    String[] split = url.getPath().split("/");
                    return split[split.length - 1];
                }).collect(Collectors.toList());
        keys.addAll(imageUrlKeys);
    }

    @Override
    public void addGoods(EditOrAddGoodsDto editOrAddGoodsDto) throws MeilisearchException {
        Goods goods = MappingUtil.mapObject(editOrAddGoodsDto, Goods.class);

        goods.setCondition(GoodsCondition.getByDetail(editOrAddGoodsDto.getConditionName()));
        goods.setCategoryId(categoryMapper.findByName(editOrAddGoodsDto.getCategoryName()).getId());
        goods.setCreateBy(Current.getCurrentUser().getUser().getId());
        goods.setUpdateBy(Current.getCurrentUser().getUser().getId());
        goods.setCreateTime(LocalDateTime.now());
        goods.setUpdateTime(LocalDateTime.now());
        goods.setStock(Integer.valueOf(editOrAddGoodsDto.getStock()));

        String code = getUniqueCode(); // 生成唯一的商品编码

        goods.setCode(code);

        goodsMapper.insert(goods);
        Integer goodsId = goods.getId();

        editOrAddGoodsDto.getPictures().forEach(imageVo -> {
            mappingGoodsImage(imageVo.getUrl(), goods.getName(), goodsId);
        });

        // 增量更新meilisearch中数据
        updateMeilisearchGoodsData(goodsId);
    }

    private @NotNull String getUniqueCode() {
        String code = GoodsCodeGenerator.generateGoodsCode();
        int retryCount = 0;
        int maxRetries = 100; // 设置一个合适的重试次数限制

        while (goodsMapper.findByCode(code) != null && retryCount < maxRetries) {
            code = GoodsCodeGenerator.generateGoodsCode();
            retryCount++;
        }

        if (retryCount == maxRetries) {
            throw new BusinessException("在" + maxRetries + "次尝试后仍无法生成唯一的商品编码。");
        }
        return code;
    }

    // 增量更新meilisearch中数据
    private void updateMeilisearchGoodsData(Integer goodsId) throws MeilisearchException {
        if (!meiliSearchEnabled) {
            log.info("meilisearch未开启，不更新meilisearch数据");
            return;
        }
        GoodsDto goodsDto = new GoodsDto();
        goodsDto.setId(goodsId);
        meiliSearchUtil.addDocument("goods", "id", JSONArray.toJSONString(getGoodsList(goodsDto).getList()));
    }

    @Override
    public void editGoods(EditOrAddGoodsDto editGoods) throws MeilisearchException {
        Goods goods = MappingUtil.mapObject(editGoods, Goods.class);
        goods.setCondition(GoodsCondition.getByDetail(editGoods.getConditionName()));
        goods.setCategoryId(categoryMapper.findByName(editGoods.getCategoryName()).getId());
        goods.setStock(Integer.parseInt(editGoods.getStock()));
        goods.setUpdateBy(Current.getCurrentUser().getUser().getId());
        goods.setUpdateTime(LocalDateTime.now());

        Integer goodsId = goods.getId();
        // 先删除数据库中图片
        imageMapper.deleteByRelatedId(goodsId, ImageType.GOODS);
        // 删除cos中图片
        ArrayList<String> keys = new ArrayList<>();
        getGoodsImageUrl(goods, keys);
        CosImageUtil.deleteBatchImage(bucketName, keys);

        // 插入新的图片
        editGoods.getPictures().forEach(imageVo -> {
            mappingGoodsImage(imageVo.getUrl(), goods.getName(), goodsId);
        });

        goodsMapper.update(goods);

        // 增量更新meilisearch中数据
        updateMeilisearchGoodsData(goodsId);
    }

    private void mappingGoodsImage(String url, String goodsName, Integer goodsId) {
        // 把图片保存进t_image
        Image image = new Image();
        image.setAltText(goodsName);
        image.setUrl(ImageUtils.getFileNameFromUrl(url));
        image.setRelatedId(goodsId);
        image.setImageType(ImageType.GOODS);
        image.setCreateTime(LocalDateTime.now());
        image.setUpdateTime(LocalDateTime.now());
        imageMapper.insert(image);
    }

    @Override
    public List<GoodsVo> getRelevantGoodsList(Integer limit) {

        List<Goods> goodsList;
        // TODO 目前返回统计表中前四的商品，后续考虑引入推荐系统
        List<Integer> goodsIds = goodsStatisticMapper.findByUserId(Current.getCurrentUser().getUser().getId());
        if (!goodsIds.isEmpty()) {
            goodsList = goodsMapper.findByGoodsIds(goodsIds);
        } else {
            goodsList = goodsMapper.findAll(new Goods());
        }
        return goodsList.stream()
                .limit(limit)
                .map(goods -> {
                    GoodsVo goodsVo = MappingUtil.mapObject(goods, GoodsVo.class);
                    eventPublisher.publishEvent(new MapGoodsImageEvent(goods, goodsVo));
                    return goodsVo;
                }).collect(Collectors.toList());
    }

    @Override
    public List<GoodsVo> searchGoods(String searchText) {
        ArrayList<GoodsVo> goodsVos = new ArrayList<>();
        if (StringUtils.isBlank(searchText)) {
            return goodsVos;
        }
        if (meiliSearchEnabled) {
            try {
                Searchable searchResult = meiliSearchUtil.searchByGoodsAttribute("goods", searchText);
//            SearchResult searchResult = MeiliSearchUtil.search("goods", searchText);
                for (HashMap<String, Object> resultHit : searchResult.getHits()) {
                    GoodsVo goodsVo = MappingUtil.melisearchResultMapToGoodsVo(resultHit);
                    goodsVo.setSellerName(userMapper.findById(goodsVo.getCreateBy()).getUsername());
                    goodsVos.add(goodsVo);
                }
            } catch (MeilisearchException e) {
                // meilisearch出现异常，去数据库查询
                searchGoodsFormData(searchText, goodsVos);
                log.error("meilisearch查询商品异常！", e);
            }
        } else {
            searchGoodsFormData(searchText, goodsVos);
        }

        return goodsVos;
    }

    // 数据库查询
    private void searchGoodsFormData(String searchText, ArrayList<GoodsVo> goodsVos) {
        Goods goods = new Goods();
        goods.setName(searchText);
        goodsVos.addAll(goodsMapper.findAll(goods).stream().map(goods1 -> {
            GoodsVo goodsVo = MappingUtil.mapObject(goods1, GoodsVo.class);
            eventPublisher.publishEvent(new MapGoodsImageEvent(goods1, goodsVo));
            return goodsVo;
        }).collect(Collectors.toList()));
    }

    @Override
    public List<GoodsConditionVo> getConditionList() {
        return Arrays.stream(GoodsCondition.values()).map(goodsCondition -> {
            GoodsConditionVo goodsConditionVo = new GoodsConditionVo();
            goodsConditionVo.setId(goodsCondition.ordinal());
            goodsConditionVo.setName(goodsCondition.getDetail());
            return goodsConditionVo;
        }).collect(Collectors.toList());
//        return goodsMapper.findAll(new Goods()).stream()
//                .collect(Collectors.groupingBy(Goods::getCondition))
//                .keySet().stream().map(goodsCondition -> {
//                    GoodsConditionVo goodsConditionVo = new GoodsConditionVo();
//                    goodsConditionVo.setId(goodsCondition.ordinal());
//                    goodsConditionVo.setName(goodsCondition.getDetail());
//                    return goodsConditionVo;
//                })
//                .sorted(Comparator.comparing(GoodsConditionVo::getId))
//                .collect(Collectors.toList());
    }

    @Override
    public ResponseEntity<byte[]> exportGoodsList(GoodsDto goodsDto) {
        Goods goods = MappingUtil.mapObject(goodsDto, Goods.class);
        if (StringUtils.isNotBlank(goodsDto.getCategoryName())) {
            goods.setCategoryId(categoryMapper.findByName(goodsDto.getCategoryName()).getId());
        }
        if (StringUtils.isNotBlank(goodsDto.getConditionName())) {
            goods.setCondition(GoodsCondition.getByDetail(goodsDto.getConditionName()));
        }

        // 如果是非管理员角色，只显示当前账号创建的商品
        if (!Current.getCurrentUser().getRoles().stream()
                .map(Role::getId).collect(Collectors.toList())
                .contains(UserRole.Admin.getCode())) {
            goods.setCreateBy(Current.getCurrentUser().getUser().getId());
        }

        List<ExcelGoodsVo> excelGoodsVoList = goodsMapper.findAll(goods).stream().map(goods1 -> {
            ExcelGoodsVo excelGoodsVo = new ExcelGoodsVo();
            excelGoodsVo.setCondition(goods1.getCondition().getDetail());
            excelGoodsVo.setName(goods1.getName());
            excelGoodsVo.setPrice(goods1.getPrice());
            excelGoodsVo.setStock(goods1.getStock());
            excelGoodsVo.setCategoryName(categoryMapper.findById(goods1.getCategoryId()).getName());
            excelGoodsVo.setDes(goods1.getDesc());
            excelGoodsVo.setCode(goods1.getCode());

            // 图片导出
            GoodsVo goodsVo = new GoodsVo();
            eventPublisher.publishEvent(new MapGoodsImageEvent(goods1, goodsVo));

            try {
                byte[] imageBytes = ImageUtils.downloadImage(goodsVo.getPicture()); // 使用新的图片下载方法
                excelGoodsVo.setPicture(imageBytes);
            } catch (IOException e) {
                log.error("商品图片读取失败！", e);
                throw new RuntimeException("商品图片读取失败！", e);
            }
            return excelGoodsVo;
        }).collect(Collectors.toList());

        return ExcelUtil.exportToExcel(excelGoodsVoList, "goodsList.xlsx", ExcelGoodsVo.class);
    }


    @Override
    public void importGoods(MultipartFile file, Boolean isCover) {
        try (InputStream inputStream = file.getInputStream()) {
            ExcelUtil.readExcel(inputStream, ExcelGoodsVo.class, new ImportGoodsVoListener(isCover, goodsMapper, categoryMapper));
        } catch (Exception e) {
            log.error("批量添加商品异常：" + e.getMessage(), e);
            throw new BusinessException("批量添加商品异常！", e);
        }
    }

    @Override
    public void saveEvaluation(List<GoodsDto> goodsDtos) {

        goodsDtos.forEach(goodsDto -> {
            Integer userId = Current.getCurrentUser().getUser().getId();
            GoodsEvaluation goodsEvaluation = new GoodsEvaluation();
            goodsEvaluation.setGoodsId(goodsDto.getId());
            goodsEvaluation.setOrderId(goodsDto.getOrderId());
            goodsEvaluation.setEvaluationInfo(goodsDto.getEvaluationInfo());
            goodsEvaluation.setCreateBy(userId);
            goodsEvaluation.setUpdateBy(userId);
            goodsEvaluation.setCreateTime(LocalDateTime.now());
            goodsEvaluation.setUpdateTime(LocalDateTime.now());
            goodsEvaluationMapper.insert(goodsEvaluation); // 保存商品评价

            // 发送消息 卖家
            Message message = new Message();
            Goods goods = goodsMapper.findById(goodsDto.getId());
            message.setRead(0);
            message.setTitle(Current.getCurrentUser().getUser().getUsername() +
                    "评价商品【" + goods.getName() + "】");
            message.setContent("评价内容：" + goodsDto.getEvaluationInfo());
            message.setMessageType(MessageType.COMMENT);
            message.setUserId(goods.getCreateBy()); // 卖家
            message.setCreateBy(userId);
            message.setUpdateBy(userId);
            message.setCreateTime(LocalDateTime.now());
            message.setUpdateTime(LocalDateTime.now());
            messageMapper.insert(message);
        });
    }
}
